﻿#include <cv.h>  
#include <highgui.h>  
#include <stdio.h>
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

using namespace cv;
IplImage* org = 0;
IplImage* img = 0;
IplImage* tmp = 0;
IplImage* dst = 0;
IplImage* img1 = 0;
void on_mouse(int event, int x, int y, int flags, void* ustc)//event鼠标事件代号，x,y鼠标坐标，flags拖拽和键盘操作的代号
{
	static CvPoint pre_pt = { -1,-1 };//初始坐标
	static CvPoint cur_pt = { -1,-1 };//实时坐标
	CvFont font;
	cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA);
	char temp[16];

	if (event == CV_EVENT_LBUTTONDOWN)//当鼠标左键按下时，读取初始坐标，并在图像该点处画圆
	{
		cvCopy(org, img);//将原始图片复制到img中
		sprintf(temp, "(%d,%d)", x, y);//格式化字符串
		pre_pt = cvPoint(x, y);//获取当前坐标值
		cvPutText(img, temp, pre_pt, &font, cvScalar(0, 0, 0, 255));//在窗口上显示坐标
		cvCircle(img, pre_pt, 3, cvScalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);//画圆
		cvShowImage("img", img);
		cvCopy(img, tmp);
	}
	else if (event == CV_EVENT_MOUSEMOVE && !(flags & CV_EVENT_FLAG_LBUTTON))//左键没有按下的情况下鼠标移动的处理函数
	{
		cvCopy(tmp, img);
		sprintf(temp, "(%d,%d)", x, y);
		cur_pt = cvPoint(x, y);
		cvPutText(img, temp, cur_pt, &font, cvScalar(0, 0, 0, 255));//只是实时显示鼠标移动的坐标
		cvShowImage("img", img);
	}
	else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))//左键按下时，鼠标移动，则在图像上画矩形
	{
		cvCopy(tmp, img);
		sprintf(temp, "(%d,%d)", x, y);
		cur_pt = cvPoint(x, y);
		cvPutText(img, temp, cur_pt, &font, cvScalar(0, 0, 0, 255));
		cvRectangle(img, pre_pt, cur_pt, cvScalar(0, 255, 0, 0), 1, 8, 0);//在临时图像上实时显示鼠标拖动时形成的矩形
		cvShowImage("img", img);
	}
	else if (event == CV_EVENT_LBUTTONUP)//左键松开，在图像上画矩形
	{
		cvCopy(tmp, img);
		sprintf(temp, "(%d,%d)", x, y);
		cur_pt = cvPoint(x, y);
		cvPutText(img, temp, cur_pt, &font, cvScalar(0, 0, 0, 255));
		cvCircle(img, cur_pt, 3, cvScalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);
		cvRectangle(img, pre_pt, cur_pt, cvScalar(0, 255, 0, 0), 1, 8, 0);//根据初始点和结束点，将矩形画在img上
		cvShowImage("img", img);
		cvCopy(img, tmp);//截取矩形包围的图像，并保存到dst中
		int width = abs(pre_pt.x - cur_pt.x);
		int height = abs(pre_pt.y - cur_pt.y);
		if (width == 0 || height == 0)
		{
			cvDestroyWindow("dst");
			return;
		}
		dst = cvCreateImage(cvSize(width, height), org->depth, org->nChannels);
		CvRect rect;
		if (pre_pt.x < cur_pt.x && pre_pt.y < cur_pt.y)
		{
			rect = cvRect(pre_pt.x, pre_pt.y, width, height);
		}
		else if (pre_pt.x > cur_pt.x && pre_pt.y < cur_pt.y)
		{
			rect = cvRect(cur_pt.x, pre_pt.y, width, height);
		}
		else if (pre_pt.x > cur_pt.x && pre_pt.y > cur_pt.y)
		{
			rect = cvRect(cur_pt.x, cur_pt.y, width, height);
		}
		else if (pre_pt.x<cur_pt.x && pre_pt.y>cur_pt.y)
		{
			rect = cvRect(pre_pt.x, cur_pt.y, width, height);
		}
		cvSetImageROI(org, rect);
		cvCopy(org, dst);
		cvResetImageROI(org);
		cvDestroyWindow("dst");
		cvNamedWindow("dst", 1);
		cvShowImage("dst", dst);
		CvScalar avgChannels = cvAvg(dst);
		double avgB = avgChannels.val[0];
		double avgG = avgChannels.val[1];
		double avgR = avgChannels.val[2];
		std::cout << avgB << " " << avgG << " " << avgR << std::endl;
		

	}
}
int main()
{
	org = cvLoadImage("第三题图.png", 1);
	img = cvCloneImage(org);
	tmp = cvCloneImage(org);
	cvNamedWindow("img", 1);
	cvSetMouseCallback("img", on_mouse, 0);//调用回调函数

	cvShowImage("img", img);
	
	cvWaitKey(0);
	cvDestroyAllWindows();
	cvReleaseImage(&org);
	cvReleaseImage(&img);
	cvReleaseImage(&tmp);
	cvReleaseImage(&dst);
	return 0;
}